/* Bitmask of physically existing CPUs */
physid_mask_t phys_cpu_present_map;
-u32 bios_cpu_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
-
/*
* Intel MP BIOS table parsing routines:
*/
static int mpc_record;
static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] __initdata;
-static void __devinit MP_processor_info (struct mpc_config_processor *m)
+/* Return xen's logical cpu_id of the new added cpu or <0 if error */
+static int __devinit MP_processor_info (struct mpc_config_processor *m)
{
- int ver, apicid;
+ int ver, apicid, cpu = 0;
physid_mask_t phys_cpu;
if (!(m->mpc_cpuflag & CPU_ENABLED))
- return;
+ return -EINVAL;
apicid = mpc_apic_id(m, translation_table[mpc_record]);
if (num_processors >= NR_CPUS) {
printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached."
" Processor ignored.\n", NR_CPUS);
- return;
+ return -ENOSPC;
}
if (num_processors >= maxcpus) {
printk(KERN_WARNING "WARNING: maxcpus limit of %i reached."
" Processor ignored.\n", maxcpus);
- return;
+ return -ENOSPC;
}
+ /* Boot cpu has been marked present in smp_prepare_boot_cpu */
+ if (!(m->mpc_cpuflag & CPU_BOOTPROCESSOR)) {
+ cpu = alloc_cpu_id();
+ if (cpu < 0) {
+ printk(KERN_WARNING "WARNING: Can't alloc cpu_id."
+ " Processor with apicid %i ignored\n", apicid);
+ return cpu;
+ }
+ x86_cpu_to_apicid[cpu] = apicid;
+ cpu_set(cpu, cpu_present_map);
+ }
+
cpu_set(num_processors, cpu_possible_map);
num_processors++;
*/
def_to_bigsmp = 1;
}
- bios_cpu_apicid[num_processors - 1] = m->mpc_apicid;
+
+ return cpu;
}
static void __init MP_bus_info (struct mpc_config_bus *m)
}
-void __devinit mp_register_lapic (
+int __devinit mp_register_lapic (
u8 id,
u8 enabled)
{
if (MAX_APICS - id <= 0) {
printk(KERN_WARNING "Processor #%d invalid (max %d)\n",
id, MAX_APICS);
- return;
+ return -EINVAL;
}
if (id == boot_cpu_physical_apicid)
processor.mpc_reserved[0] = 0;
processor.mpc_reserved[1] = 0;
- MP_processor_info(&processor);
+ return MP_processor_info(&processor);
}
#ifdef CONFIG_X86_IO_APIC
#endif /* WAKE_SECONDARY_VIA_INIT */
extern cpumask_t cpu_initialized;
-static inline int alloc_cpu_id(void)
+/*
+ * Caller should hold cpu_add_remove_lock if not called when booting
+ */
+int alloc_cpu_id(void)
{
cpumask_t tmp_map;
int cpu;
cpu_clear(cpu, cpu_callout_map); /* was set here (do_boot_cpu()) */
cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */
cpucount--;
+
+ /* Mark the CPU as non-present */
+ spin_lock(&cpu_add_remove_lock);
+ x86_cpu_to_apicid[cpu] = BAD_APICID;
+ cpu_clear(cpu, cpu_present_map);
+ spin_unlock(&cpu_add_remove_lock);
} else {
- x86_cpu_to_apicid[cpu] = apicid;
- cpu_set(cpu, cpu_present_map);
}
/* mark "stuck" area as not stuck */
static void __init smp_boot_cpus(unsigned int max_cpus)
{
- int apicid, cpu, bit, kicked;
+ int apicid, cpu, kicked;
#ifdef BOGOMIPS
unsigned long bogosum = 0;
#endif
Dprintk("CPU present map: %lx\n", physids_coerce(phys_cpu_present_map));
kicked = 1;
- for (bit = 0; kicked < NR_CPUS && bit < NR_CPUS; bit++) {
- apicid = cpu_present_to_apicid(bit);
+
+ for_each_present_cpu ( cpu )
+ {
+ apicid = x86_cpu_to_apicid[cpu];
+
/*
* Don't even attempt to start the boot CPU!
*/
continue;
if (!check_apicid_present(apicid))
+ {
+ dprintk(XENLOG_WARNING, "Present CPU has valid apicid\n");
continue;
+ }
+
if (max_cpus <= cpucount+1)
continue;
- if (((cpu = alloc_cpu_id()) <= 0) || do_boot_cpu(apicid, cpu))
+ if ( do_boot_cpu(apicid, cpu))
printk("CPU #%d not responding - cannot use it.\n",
apicid);
else
#define apicid_to_node(apicid) ((int)apicid_to_node[(u32)apicid])
extern u32 bios_cpu_apicid[];
-static inline int cpu_present_to_apicid(int mps_cpu)
-{
- if (mps_cpu < NR_CPUS)
- return (int)bios_cpu_apicid[mps_cpu];
- else
- return BAD_APICID;
-}
static inline int mpc_apic_id(struct mpc_config_processor *m,
struct mpc_config_translation *translation_record)
extern int using_apic_timer;
#ifdef CONFIG_ACPI
-extern void mp_register_lapic (u8 id, u8 enabled);
+extern int mp_register_lapic (u8 id, u8 enabled);
+extern void mp_unregister_lapic(uint32_t apic_id, uint32_t cpu);
extern void mp_register_lapic_address (u64 address);
extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base);
extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, u32 gsi);
#define lock_cpu_hotplug() ((void)0)
#define unlock_cpu_hotplug() ((void)0)
+int alloc_cpu_id(void);
+
#endif /* __XEN_SMP_H__ */